package wechat.core;

import org.nutz.lang.Lang;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.xml.sax.SAXException;
import wechat.vo.*;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

/**
 * Created by jiangjunguo on 16-6-28.
 */
public class WechatCore {

    private static final Log log = Logs.get();

    /**
     * 微信账户信息
     */
    private WeChatAccount account;

    /**
     * request请求参数
     */
    private Map<String, String[]> reqParams;

    // XML解析准备
    private SAXParserFactory factory = SAXParserFactory.newInstance();
    private SAXParser xmlParser;
    private MessageHandler msgHandler = new MessageHandler();


    public WechatCore() throws ParserConfigurationException, SAXException {
        xmlParser = factory.newSAXParser();
    }

    /**
     * 设置微信账户信息
     *
     * @param account
     */
    public void setAccount(WeChatAccount account) {
        this.account = account;
    }


    public WeChatAccount getAccount() {
        return account;
    }

    /**
     * 设置请求参数
     *
     * @param reqParams 请求参数
     */
    public void setReqParams(Map<String, String[]> reqParams) {
        this.reqParams = reqParams;
    }

    /**
     * 验证服务器认证签名
     *
     * @return
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     */
    public String checkSignature() throws UnsupportedEncodingException, NoSuchAlgorithmException {

        String signature = this.getParam("signature");
        String timestamp = this.getParam("timestamp");
        String nonce = this.getParam("nonce");

        String validsign = SignatureTools.calculateSHA1(account.getToken(), timestamp, nonce);
        if (log.isDebugEnabled()) {
            log.debugf("Valid wechat server sign %b. sign: %s",
                    Lang.equals(validsign, signature),
                    validsign);
        }

        if (signature.equals(validsign)) {
            return this.getParam("echostr");
        }

        return "error";
    }

    /**
     * 处理普通消息
     *
     * @param inputStream
     */
    public void handle(InputStream inputStream) throws IOException, SAXException {

        xmlParser.parse(inputStream, msgHandler);
        BasicMessage message = getHandleMsg(msgHandler.getValues());

        //TODO

    }

    private BasicMessage getHandleMsg(Map<String, String> values) {
        BasicMessage message = null;

        switch (values.get("MsgType")) {
            case "text":
                message = new TextMessage(values);
                break;

            case "image":
                message = new ImageMessage(values);
                break;

            case "voice":
                message = new VoiceMessage(values);
                break;

            case "video":
                message = new VideoMessage(values);
                break;

            case "shortvideo":
                message = new ShortVideoMessage(values);
                break;

            case "location":
                message = new LocationMessage(values);
                break;
        }

        return message;
    }

    /**
     * 获取请求参数
     *
     * @param paramName 参数名称
     * @return
     */
    private String getParam(String paramName) {
        return reqParams.get(paramName)[0];
    }

    public void getUserAccessToken() {
        this.account.getUserAccessToken();
    }

    public String register(String scope, String callbackUrl) {
        return this.account.register(scope, callbackUrl);
    }

    public UserAccessTokenResponse getUserAccessToken(String code) {
        return this.account.getUserAccessToken(code);
    }
}
